<?php

declare(strict_types=1);

namespace App\Services\Sms;

use Aliyun\Api\Sms\Request\V20170525\QuerySendDetailsRequest;
use Aliyun\Api\Sms\Request\V20170525\SendSmsRequest;
use Aliyun\Core\Config as AliyunConfig;
use Aliyun\Core\DefaultAcsClient;
use Aliyun\Core\Profile\DefaultProfile;
use App\Entity\SmsEntity;
use Illuminate\Support\Facades\Log;
use stdClass;

// 初始化
AliyunConfig::load();

/**
 * 短信发送服务
 * Class SmsService
 */
class SmsService
{
    public static $acsClient = null;

    /**
     * 取得AcsClient
     *
     * @return DefaultAcsClient
     */
    public static function getAcsClient()
    {
        //产品名称:云通信短信服务API产品,开发者无需替换
        $product = 'Dysmsapi';

        //产品域名,开发者无需替换
        $domain = 'dysmsapi.aliyuncs.com';

        // 此处需要替换成开发者自己的AK (https://ak-console.aliyun.com/)
        $accessKeyId = config('sms.accessKeyId');

        $accessKeySecret = config('sms.accessKeySecret');

        // 暂时不支持多Region
        $region = 'cn-hangzhou';

        // 服务结点
        $endPointName = 'cn-hangzhou';

        if (static::$acsClient == null) {
            //初始化acsClient,暂不支持region化
            $profile = DefaultProfile::getProfile($region, $accessKeyId, $accessKeySecret);

            // 增加服务结点
            DefaultProfile::addEndpoint($endPointName, $region, $product, $domain);

            // 初始化AcsClient用于发起请求
            static::$acsClient = new DefaultAcsClient($profile);
        }

        return static::$acsClient;
    }

    /**
     * 发送短信
     *
     * @return bool
     *              $smsEntity = app(SmsEntity::class);
     *              $smsEntity->signName = $newRes->signName ?? config('sms.defaultSignName');
     *              $smsEntity->phone = $newRes->phone;
     *              $smsEntity->templateCode = $newRes->templateCode;
     *              $smsEntity->templateParam = $newRes->templateParam;
     *              SmsService::sendSms($smsEntity);
     */
    public static function sendSms(SmsEntity $smsEntity)
    {
        // 初始化SendSmsRequest实例用于设置发送短信的参数
        $request = new SendSmsRequest();

        //可选-启用https协议
        //$request->setProtocol("https");

        // 必填，设置短信接收号码

        $request->setPhoneNumbers($smsEntity->phone);

        // 必填，设置签名名称，应严格按"签名名称"填写，请参考: https://dysms.console.aliyun.com/dysms.htm#/develop/sign
        $request->setSignName($smsEntity->signName ?? config('sms.defaultSignName'));

        // 必填，设置模板CODE，SMS_155860249
        $request->setTemplateCode($smsEntity->templateCode);

        // 可选，设置模板参数, 假如模板中存在变量需要替换则为必填项
        $request->setTemplateParam(json_encode($smsEntity->templateParam, JSON_UNESCAPED_UNICODE));

        // 可选，设置流水号
        //$request->setOutId("yourOutId");

        // 选填，上行短信扩展码（扩展码字段控制在7位或以下，无特殊需求用户请忽略此字段）
        //$request->setSmsUpExtendCode("1234567");

        // 发起访问请求
        $acsResponse = static::getAcsClient()->getAcsResponse($request);

        // 默认返回stdClass，通过返回值的Code属性来判断发送成功与否
        if ($acsResponse && strtolower($acsResponse->Code) == 'ok') {
            return true;
        }
        Log::error('短信发送失败', (array) $acsResponse);

        return false;
    }

    /**
     * 短信发送记录查询
     *
     * @param null $date
     *
     * @return stdClass
     */
    public static function querySendDetails(string $phone, $date = null)
    {
        if ($date == null) {
            $date = date('Ymd', time());
        }
        // 初始化QuerySendDetailsRequest实例用于设置短信查询的参数
        $request = new QuerySendDetailsRequest();

        //可选-启用https协议
        //$request->setProtocol("https");

        // 必填，短信接收号码
        $request->setPhoneNumber($phone);

        // 必填，短信发送日期，格式Ymd，支持近30天记录查询
        $request->setSendDate($date);

        // 必填，分页大小
        $request->setPageSize(10);

        // 必填，当前页码
        $request->setCurrentPage(1);

        // 选填，短信发送流水号
        //$request->setBizId("yourBizId");

        // 发起访问请求
        $acsResponse = static::getAcsClient()->getAcsResponse($request);

        return $acsResponse;
    }
}
